package ci.web.router;

import io.netty.handler.codec.http.HttpResponseStatus;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

import ci.web.core.CiContext;

/**
 * 利用构造函数做处理
 * @author zhh
 */
public class CiConstructorHandler extends CiHandler {

    public CiConstructorHandler(String pkg, Method method) {
        super(pkg, method);
    }

    public CiConstructorHandler(String pkg, Constructor<?> c){
        className = c.getDeclaringClass().getCanonicalName();
        methodName = "/";
        paramTypes = c.getParameterTypes();
        path = buildPath(c, pkg, className, methodName);
        pathArg = isPathArg(c);
        _hashcode = pathArg?(path+"@").hashCode():path.hashCode();        
    }
    
    @Override
    public String toString() {
        return String.format("{p:%s, j:%s.%s, p:%d}", path, className, "()", paramTypes.length);
//        return super.toString();
    }
    
    /**
     * 执行处理
     * @param ctx
     * @return
     * @throws Exception
     */
    public boolean call(CiContext ctx, ClassLoader loader) throws Exception {
        Class<?> clazz = loader.loadClass(className);
        Constructor<?> method = clazz.getConstructor(paramTypes);
//        method.setAccessible(true);
        if(isAlowMethod(method, ctx.in().method())==false){
            ctx.out().setStatus(HttpResponseStatus.FORBIDDEN);
        }else{
            Object[] args = castArgs(ctx, method, path);
            method.newInstance(args);
        }
        return true;
    }
    
    /**
     * 寻找符合Ci构造函数的路由
     * @param clazz
     * @return
     */
    public static CiHandler tryMake(Class<?> clazz, String packageName) {
        for(Constructor<?> constructor : clazz.getConstructors()){
            if(constructor.getParameterCount()>0){
                if(check(constructor)){
                    return new CiConstructorHandler(packageName, constructor);
                }
            }
        }
        return null;
    }
    
}
